﻿using System;
using System.Linq.Expressions;
using System.Collections;
using System.Collections.Generic;

namespace Devtm.ServiceModel.Discovery.Collection
{
    public class IndexMultipleCollection<T, TKey, TIndex> : TableCollection<ITableCollection<T,TKey>, TIndex>
    {


        #region private

        internal Expression<Func<T, TIndex>> Filter;
        private Func<T, TIndex> _filter;

        #endregion



        #region ctor / ~

        public IndexMultipleCollection(
            ITableCollection<T, TKey> source, 
            Expression<Func<T, TIndex>> filter
            )
        {

            this.Source = source;
            this._filter = filter.Compile();
            this.Filter = filter;

            IndexName = TableCollection.GetNameProperty(filter);

            foreach (T item in source)
                AddItem(_filter(item));

            source.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(source_CollectionChanged);
        
        }

        private void AddItem(TIndex p)
        {
            if (!ContainsKey(p))
            {
                var i = Source.GetView(c => Equals(_filter(c), p));
                this.Add(p, i);
            }
        }

        private void DelItem(TIndex p)
        {

            if (ContainsKey(p))
                if (this[p].Count == 0)
                    base.RemoveKey(p);
            
        }


        #endregion

        #region Events


        void source_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {

            e.ApplyChange<T>
             (
                 item =>                        // Add
                 {
                     TIndex p = _filter(item);
                     AddItem(p);
                 },     
                 item =>                        // remove
                 {
                     TIndex p = _filter(item);
                     DelItem(p);
                 },  
                 () => Clear()                  // Clear
             );

            //if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
            //    Clear();

            //else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
            //{
            //    if (e.NewItems is IEnumerable)
            //        foreach (IList<T> item in e.NewItems)
            //            foreach (T item3 in item)
            //            {
            //                TIndex p = _filter(item3);
            //                AddItem(p);
            //            }


            //    else
            //        foreach (T item in e.NewItems)
            //        {
            //            TIndex p = _filter(item);
            //            AddItem(p);
            //        }

            //}

            //else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
            //{

            //    if (e.OldItems is IEnumerable)
            //        foreach (IList<T> item2 in e.OldItems)
            //            foreach (T item4 in item2)
            //            {
            //                TIndex p = _filter(item4);
            //                DelItem(p);
            //            }

            //    else
            //        foreach (T item2 in e.OldItems)
            //        {
            //            TIndex p = _filter(item2);
            //            DelItem(p);
            //        }
            //}


        }

        #endregion

        public string IndexName { get; private set; }


        public ITableCollection<T, TKey> Source { get; private set; }

    }
}
